package com.sari.common.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sari.common.config.Global;
import com.sari.common.utils.DateUtils;
import com.sari.common.utils.StringUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Validator;
import java.beans.PropertyEditorSupport;
import java.util.Date;

/**
 * 控制器支持类
 */
public abstract class BaseController {

    /**
     * 日志对象
     */
    protected Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 验证Bean实例对象
     */
    @Autowired
    protected Validator validator;

//    /**
//     * 服务端参数有效性验证
//     *
//     * @param object 验证的实体对象
//     * @param groups 验证组
//     * @return 验证成功：返回true；严重失败：将错误信息添加到 message 中
//     */
//    protected boolean beanValidator(Model model, Object object, Class<?>... groups) {
//        try {
//            BeanValidators.validateWithException(validator, object, groups);
//        } catch (ConstraintViolationException ex) {
//            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
//            list.add(0, "数据验证失败：");
//            addMessage(model, list.toArray(new String[]{}));
//            return false;
//        }
//        return true;
//    }
//
//    /**
//     * 服务端参数有效性验证
//     *
//     * @param object 验证的实体对象
//     * @param groups 验证组
//     * @return 验证成功：返回true；严重失败：将错误信息添加到 flash message 中
//     */
//    protected boolean beanValidator(RedirectAttributes redirectAttributes, Object object, Class<?>... groups) {
//        try {
//            BeanValidators.validateWithException(validator, object, groups);
//        } catch (ConstraintViolationException ex) {
//            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
//            list.add(0, "数据验证失败：");
//            addMessage(redirectAttributes, list.toArray(new String[]{}));
//            return false;
//        }
//        return true;
//    }

    /**
     * 添加Model消息
     *
     * @param messages 消息
     */
    protected void addMessage(Model model, String... messages) {
        StringBuilder sb = new StringBuilder();
        for (String message : messages) {
            sb.append(message).append(messages.length > 1 ? "<br/>" : "");
        }
        model.addAttribute("message", sb.toString());
    }

    /**
     * 添加Flash消息
     *
     * @param messages 消息
     */
    protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
        StringBuilder sb = new StringBuilder();
        for (String message : messages) {
            sb.append(message).append(messages.length > 1 ? "<br/>" : "");
        }
        redirectAttributes.addFlashAttribute("message", sb.toString());
    }

    /**
     * 初始化数据绑定
     * 1. 将所有传递进来的String进行HTML编码，防止XSS攻击
     * 2. 将字段中Date类型转换为String类型
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        // String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
        binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
            }

            @Override
            public String getAsText() {
                Object value = getValue();
                return value != null ? value.toString() : "";
            }
        });
        // Date 类型转换
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtils.parseDate(text));
            }
        });
    }

    @ModelAttribute(Global.JsonKey)
    public JSON jsonParamInit(@RequestParam(value = Global.JsonKey, required = false) String json) {
        if (StringUtils.isNotBlank(json)) {
            json = StringEscapeUtils.unescapeHtml4(json);
            if (StringUtils.endsWith(json, "]") && StringUtils.startsWith(json, "[")) {
                return JSON.parseArray(json);
            } else if (StringUtils.endsWith(json, "}") && StringUtils.startsWith(json, "{")) {
                return JSON.parseObject(json);
            }
        }
        return new JSONObject();
    }

}
